package com.pince.playStream.player

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
import com.pili.pldroid.player.AVOptions
import com.pili.pldroid.player.PLOnErrorListener
import com.pili.pldroid.player.PLOnInfoListener
import com.pili.pldroid.player.widget.PLVideoTextureView
import com.pince.playStream.player.widget.MediaController


open class PLPlayerController : FrameLayout {

    var params: LayoutParams = LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT,
            Gravity.CENTER)
    lateinit var mediaController: MediaController
    var mVideoView: PLVideoTextureView? = null
    var isNeedStartFirst = true
    var isPlaying = false

    companion object {
        var isDebug = true
        val TAG = "PLPlayer_"
    }

    //构造函数
    constructor(context: Context) : super(context)

    constructor(context: Context, mAttributeSet: AttributeSet?) : super(context, mAttributeSet)

    init {
        //创建一个空的界面
    }

    fun initPlayer(path: String) {
        mVideoView = PLVideoTextureView(context)
        this.addView(mVideoView, params)
        mVideoView!!.let {
            it.displayAspectRatio = PLVideoTextureView.ASPECT_RATIO_PAVED_PARENT
            it.setAVOptions(getPlayAVOptionsConfig())

            //设置各种监听 业务层可以操作
//        it.setOnPreparedListener(this);
            it.setOnInfoListener(mOnInfoListener);
//        it.setOnCompletionListener(this);
//        it.setOnVideoSizeChangedListener(this);
            it.setOnErrorListener(mOnErrorListener);
            it.setVideoPath(path)
            if (isNeedStartFirst) {
                onPlayerStart()
            }
        }
    }


    /**
     * 播放器配置
     */
    fun getPlayAVOptionsConfig(): AVOptions {
        val options = AVOptions()
        // DNS 服务器设置
        // 若不设置此项，则默认使用 DNSPod 的 httpdns 服务
        // 若设置为 127.0.0.1，则会使用系统的 DNS 服务器
        // 若设置为其他 DNS 服务器地址，则会使用设置的服务器
//        options.setString(AVOptions.KEY_DNS_SERVER, server);

        // 默认值是：MEDIA_CODEC_SW_DECODE
        options.setInteger(AVOptions.KEY_MEDIACODEC, AVOptions.MEDIA_CODEC_AUTO)
        // 是否开启直播优化，1 为开启，0 为关闭。若开启，视频暂停后再次开始播放时会触发追帧机制
        // 默认为 0
        options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1)
        // 快开模式，启用后会加快该播放器实例再次打开相同协议的视频流的速度
        options.setInteger(AVOptions.KEY_FAST_OPEN, 1)
        // 打开重试次数，设置后若打开流地址失败，则会进行重试
        options.setInteger(AVOptions.KEY_OPEN_RETRY_TIMES, 5)
        // 预设置 SDK 的 log 等级， 0-4 分别为 v/d/i/w/e
        options.setInteger(AVOptions.KEY_LOG_LEVEL, 0);
        // 打开视频时单次 http 请求的超时时间，一次打开过程最多尝试五次
        // 单位为 ms
        options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000)
        // 默认的缓存大小，单位是 ms
        // 默认值是：500
        options.setInteger(AVOptions.KEY_CACHE_BUFFER_DURATION, 500)
        // 最大的缓存大小，单位是 ms
        // 默认值是：2000，若设置值小于 KEY_CACHE_BUFFER_DURATION 则不会生效
        options.setInteger(AVOptions.KEY_MAX_CACHE_BUFFER_DURATION, 4000)
        // 设置偏好的视频格式，设置后会加快对应格式视频流的打开速度，但播放其他格式会出错
        // m3u8 = 1, mp4 = 2, flv = 3
        options.setInteger(AVOptions.KEY_PREFER_FORMAT, 3)
        // 开启解码后的视频数据回调
        // 默认值为 0，设置为 1 则开启
        options.setInteger(AVOptions.KEY_VIDEO_DATA_CALLBACK, 0)
        // 开启解码后的音频数据回调
        // 默认值为 0，设置为 1 则开启
        options.setInteger(AVOptions.KEY_VIDEO_DATA_CALLBACK, 0)
        // 设置开始播放位置
        // 默认不开启，单位为 ms
//        options.setInteger(AVOptions.KEY_START_POSITION, 10 * 1000)
        return options
    }


    fun onPlayerStart() {
        if (mVideoView != null) {
            Log.e(TAG, "onPlayerStart.. ")
            isPlaying = true
            mVideoView!!.start()
        }
    }

    fun onPlayerResume() {
        if (mVideoView != null && isPlaying) {
            Log.e(TAG, "onPlayerResume.. ")
            mVideoView!!.start()
        }
    }


    fun onPlayePause() {
        if (mVideoView != null && isPlaying) {
            Log.e(TAG, "onPlayePause.. ")
            mVideoView!!.pause()
        }
    }

    fun onPlayeStop() {
        if (mVideoView != null && isPlaying) {
            Log.e(TAG, "onPlayeStop.. ")
            isPlaying = false
            mVideoView!!.stopPlayback()
        }
    }

    private val mOnErrorListener = PLOnErrorListener { errorCode ->
        when (errorCode) {
            PLOnErrorListener.ERROR_CODE_IO_ERROR -> {
                setLogs("网络异常")
                return@PLOnErrorListener false
            }
            PLOnErrorListener.ERROR_CODE_OPEN_FAILED -> {
                setLogs("预加载失败")
            }
            PLOnErrorListener.ERROR_CODE_PLAYER_VERSION_NOT_MATCH -> {
                setLogs("so 库版本不匹配，需要升级")
                return@PLOnErrorListener true
            }
            else -> {

            }
        }
        true
    }


    private val mOnInfoListener = PLOnInfoListener { what, extra ->
        when (what) {
            PLOnInfoListener.MEDIA_INFO_BUFFERING_START -> {
                //开始缓冲
                setLogs("开始缓冲..$extra")
            }
            PLOnInfoListener.MEDIA_INFO_BUFFERING_END -> {
                //停止缓冲
                setLogs("停止缓冲..$extra")
            }
            PLOnInfoListener.MEDIA_INFO_VIDEO_RENDERING_START -> {
                //第一帧视频已成功渲染
                setLogs("第一帧视频已成功渲染..$extra")
            }
            PLOnInfoListener.MEDIA_INFO_AUDIO_RENDERING_START -> {
                //第一帧音频已成功播放
                setLogs("第一帧音频已成功播放..$extra")
            }
            PLOnInfoListener.MEDIA_INFO_VIDEO_GOP_TIME -> {
//                获取视频的I帧间隔
                setLogs("获取视频的I帧间隔..$extra")
            }

            PLOnInfoListener.MEDIA_INFO_VIDEO_FPS -> {
//                视频的帧率统计结果
                setLogs("视频的帧率统计结果.." + updateStatInfo())
            }
            PLOnInfoListener.MEDIA_INFO_CONNECTED -> {
//                连接成功
                setLogs("连接成功..$extra")
            }
            PLOnInfoListener.MEDIA_INFO_VIDEO_ROTATION_CHANGED -> {
//                获取到视频的播放角度
            }
            else -> {
            }
        }
    }

    fun setLogs(string: String) {
        if (isDebug) {
            Log.e(TAG, string)
        }
    }

    fun updateStatInfo(): String {
        mVideoView?.let {
            val bitrate = it.videoBitrate / 1024
            val stat = bitrate.toString() + "kbps, " + it.videoFps + "fps"
            return stat
        }
        return ""
    }
}